package io.mft.datasource.db.accessor.impl;

import io.mft.commons.db.SQL;
import io.mft.commons.db.mapper.SQLExecutorDbMapper;
import io.mft.commons.exception.MFTException;
import io.mft.commons.function.ExecuteReturn;
import io.mft.commons.function.response.kv.KVMap;
import io.mft.datasource.db.accessor.DataAccessor;
import io.mft.datasource.db.accessor.bean.DAContext;
import io.mft.datasource.db.accessor.bean.DbContextValue;
import io.mft.datasource.db.accessor.sql.SQLScript;
import io.mft.datasource.db.accessor.sql.SQLScriptManager;
import io.mft.datasource.db.accessor.util.ProcedureFunctionSQLParameterTypeBuilder;

public abstract class DbUnQueryExecuteAccessor extends DataAccessor<DbContextValue>{

	@Override
	public ExecuteReturn doExecute(DAContext<DbContextValue> context) {
		try {
			DbContextValue dbContextValue = context.getContextValue();
			SQLScript sqlScript = SQLScriptManager.getInstance().get(dbContextValue.getScriptKey());
			if (sqlScript==null) {
				throw new MFTException("SQL对象["+dbContextValue.getScriptKey()+"]不存在");
			}
			switch (sqlScript.getType()) {
			case table:
				 executeTable(context);
				 break;
			case sql:
				SQL sql = SQLScriptManager.getInstance().loadSQL(dbContextValue.getScriptKey(), context.getRequest().getRequestValue());
				SQLExecutorDbMapper<KVMap> sqlExecutorDbMapper=SQLExecutorDbMapper.getInstance(dbContextValue.getDatasourceId(), KVMap.class);
				sqlExecutorDbMapper.executeBysql(sql.getSql(), sql.getArgs());
				break;
			case sqlfunction:
				SQL sqlfunction = SQLScriptManager.getInstance().loadSQL(dbContextValue.getScriptKey(), context.getRequest().getRequestValue());
				SQLExecutorDbMapper<KVMap> sqlfunctionExecutorDbMapper=SQLExecutorDbMapper.getInstance(dbContextValue.getDatasourceId(), KVMap.class);
				String[] fparamTypes=ProcedureFunctionSQLParameterTypeBuilder.build(sqlfunction, context.getRequest().getRequestValue());
				sqlfunctionExecutorDbMapper.executeFunction(sqlfunction.getSql(), fparamTypes,sqlfunction.getArgs());
				break;
			case sqlprocedure:
				SQL sqlprocedure = SQLScriptManager.getInstance().loadSQL(dbContextValue.getScriptKey(), context.getRequest().getRequestValue());
				String[] paramTypes=ProcedureFunctionSQLParameterTypeBuilder.build(sqlprocedure, context.getRequest().getRequestValue());
				SQLExecutorDbMapper<KVMap> sqlprocedureExecutorDbMapper=SQLExecutorDbMapper.getInstance(dbContextValue.getDatasourceId(), KVMap.class);
				sqlprocedureExecutorDbMapper.executeFunction(sqlprocedure.getSql(),paramTypes, sqlprocedure.getArgs());
				break;
			default:
				throw new MFTException(-1, "不支持的SQLScript类型");
			}
			ExecuteReturn executeReturn=ExecuteReturn.builder().build();
			return executeReturn;
		} catch (Exception e) {
			throw new MFTException(e);
		}
	}

	protected abstract ExecuteReturn executeTable(DAContext<DbContextValue> context) throws Exception;
}
